package com.snow.auth.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.snow.annotation.SysLog;
import com.snow.auth.entity.SystemUser;
import com.snow.auth.entity.SystemUserPostEntity;
import com.snow.auth.entity.SystemUserRole;
import com.snow.auth.repository.SystemUserPostRepository;
import com.snow.auth.service.SystemUserService;
import com.snow.conditions.ConditionType;
import com.snow.conditions.DayTimeOffset;
import com.snow.conditions.QueryConditionField;
import com.snow.jpa.model.BasePageParams;
import com.snow.jpa.model.IBaseSearchParams;
import com.snow.model.IdParams;
import com.snow.model.PhoneParams;
import com.snow.view.IWebResponse;
import com.snow.view.PageData;
import com.snow.view.WebResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author by 13119
 */
@RequestMapping("/system-user")
@RestController
@AllArgsConstructor
public class SystemUserController {
    final SystemUserService systemUserService;
    private final SystemUserPostRepository systemUserPostRepository;

    @Getter
    @Setter
    public static class CreateParams {
        @NotNull(message = "所属部门不能为空")
        private Integer deptId;
        @NotNull(message = "登录账户不能为空")
        private String account;
        @NotNull(message = "真实姓名不能为空")
        private String realName;
        private String avatar = "";
        private String email = "";
        private String phone = "";
        /**
         * 角色列表
         */
        @NotEmpty(message = "角色列表不能为空")
        private Integer[] roleIds;
        private Integer[] postIds;
        private Integer dataScope;
    }

    @SysLog("创建用户")
    @PostMapping("/create")
    public IWebResponse create(@Validated @RequestBody CreateParams params) {
        return systemUserService.create(params);
    }

    @Getter
    @Setter
    public static class PageParams extends BasePageParams {
        @QueryConditionField
        private Integer deptId;
        @QueryConditionField(value = "deptId", type = ConditionType.in)
        public Integer[] deptIds;
        @QueryConditionField(type = ConditionType.greaterThanOrEqual, value = "createTime")
        private Date startTime;
        @QueryConditionField(type = ConditionType.lessThanOrEqual, value = "createTime", dateOffset = DayTimeOffset.END)
        private Date endTime;
    }

    @SysLog("分页查询用户列表")
    @PostMapping("/page")
    public WebResponse<PageData<SystemUser>> page(@RequestBody PageParams params) {
        PageData<SystemUser> pageData = systemUserService.page(params);
        for (SystemUser systemUser : pageData.getList()) {
            systemUser.setPassword("******");
        }
        return WebResponse.success(pageData);
    }

    @Getter
    @Setter
    public static class UpdateParams {
        @NotNull(message = "更新主键不能为空")
        private Integer id;
        private Integer deptId;
        private String email;
        private String realName;
        @NotEmpty(message = "角色列表不能为空")
        private Integer[] roleIds;
        private Integer[] postIds;
        private Integer dataScope;
    }

    @PostMapping("/update")
    public IWebResponse update(@RequestBody UpdateParams params) {
        systemUserService.update(params);
        return WebResponse.success();

    }

    @SysLog("删除用户")
    @PostMapping("/delete")
    public IWebResponse delete(@RequestBody IdParams params) {
        return WebResponse.success(systemUserService.delete(params.getId()));
    }

    @GetMapping("/get-all")
    public IWebResponse getAll() {
        return WebResponse.success(systemUserService.search(null));
    }

    @Getter
    @Setter
    public static class BindParams {
        private String openId;
        private Integer userId;
    }

    @PostMapping("/bind-wechat")
    public IWebResponse bindWeChat(@RequestBody BindParams params) {
        systemUserService.bindWeChat(params);
        return WebResponse.success();
    }

    @PostMapping("/unbind-wechat")
    public IWebResponse unbindWeChat(@RequestBody IdParams params) {
        systemUserService.unbindWeChat(params.getId());
        return WebResponse.success();
    }

    @Data
    public static class SearchParams implements IBaseSearchParams {
        @QueryConditionField(type = ConditionType.like)
        private String realName;
        @QueryConditionField
        private Integer deptId;
    }

    @PostMapping("/search")
    public WebResponse<List<SystemUser>> search(@RequestBody SearchParams searchParams) {
        return WebResponse.success(systemUserService.search(searchParams));
    }

    @Data
    @AllArgsConstructor
    public static class IndexUser {
        List<String> indexKeys;
        List<List<SystemUser>> users;
    }

    @PostMapping("/search-index")
    public WebResponse<IndexUser> searchByIndex(@RequestBody SearchParams searchParams) {
        List<SystemUser> users = systemUserService.search(searchParams);
        Map<String, List<SystemUser>> indexes = new HashMap<>();
        for (SystemUser user : users) {
            String indexKey = PinyinUtil.getFirstLetter(user.getRealName(), "").substring(0, 1).toUpperCase(Locale.ROOT);
            if (indexes.containsKey(indexKey)) {
                indexes.get(indexKey).add(user);
            } else {
                indexes.put(indexKey, CollUtil.newArrayList(user));
            }
        }
        List<List<SystemUser>> indexList = new ArrayList<>();
        List<String> keys = new ArrayList<>();
        indexes.keySet().stream().sorted().forEach(indexKey -> {
            keys.add(indexKey);
            indexList.add(indexes.get(indexKey));
        });
        return WebResponse.success(new IndexUser(keys, indexList));

    }

    @PostMapping("/getDetails")
    public WebResponse<SystemUser> getDetails(@RequestBody IdParams params) {
        SystemUser systemUser = systemUserService.get(params.getId());
        List<Integer> roleIds = systemUserService.getSystemUserRoleRepository().lambdaQuery().equal("userId", systemUser.getId()).findAll().stream()
                .map(SystemUserRole::getRoleId).collect(Collectors.toList());
        systemUser.setPassword("");
        systemUser.setRoleIds(roleIds);
        List<Integer> postIds = systemUserPostRepository.findAllBy("userId", systemUser.getId()).stream()
                .map(SystemUserPostEntity::getPostId).collect(Collectors.toList());
        systemUser.setPostIds(postIds);
        return WebResponse.success(systemUser);
    }

    @Getter
    @Setter
    public static class LinkWechatParams {
        private Integer userId;
        private String phone;
    }

    @PostMapping("/link-wechat")
    public WebResponse<Void> linkWechat(@RequestBody LinkWechatParams params) {
        systemUserService.linkWechat(params);
        return WebResponse.success();
    }
}
